import time
from pages.excel_data_extraction import Excel_data_extraction
from config.settings import get_config
from base.base_page import BasePage

"""
封装功能函数

"""
class New_Interface_Page(BasePage):
    def __init__(self, driver, device_type, logger=None):
        super().__init__(driver, device_type, logger=logger)  # 传递日志实例
        self.driver = driver
        self.config = get_config(device_type)  # 获取全局配置
        self.excel_processor = Excel_data_extraction(self.driver, device_type, logger=logger)

    ########################################  新建数据接口  ########################################

    def new_interface_page(self, belong_to_object, direction, interface_name, token_name, description,
                           server_protocol, server_ip, server_port, server_path, client_protocol,
                           req_method, client_ip, client_port, client_path):
        # 1.进入基本可用配置界面--新建数据接口
        self.enter_new_interface_page()
        self.update_interface_status(interface_name, '停止')
        self.delete_interface_page(interface_name)
        # 2.点击新建按钮
        self.newly_built_interface()
        # 3.选择所属业务对象
        self.input_belong_to_object(belong_to_object)
        # 4.输入接口方向
        self.input_interface_direction(direction)
        # 5.选择接口令牌
        self.input_token(direction, token_name)
        # 6.请输入接口名称
        self.input_interface_name(interface_name)
        # 7.请说明此数据接口用途
        self.input_interface_description(description)
        # 8.选择服务路径的接口协议
        self.input_server_protocol(server_protocol)
        # 9.输入服务路径的数据接口路径地址IP
        self.input_server_interface_ip(server_ip)
        # 10.输入服务路径的数据接口端口
        self.input_server_interface_port(server_port)
        # 11.输入服务路径的数据接口路径
        self.input_server_interface_path(server_path)
        # 12.选择网关路径的接口协议
        self.input_client_protocol(client_protocol)
        # 13.选择网关路径的请求方式
        self.input_client_req_method(req_method)
        # 14.输入网关路径的数据接口路径地址IP
        self.input_client_interface_ip(client_ip)
        # 15.输入网关路径的数据接口路径
        self.input_client_interface_port(client_port)
        # 16.输入网关路径的数据接口路径
        self.input_client_interface_path(client_path)
        # 17.保存数据接口
        self.save_data_interface(interface_name)

    def enter_new_interface_page(self):
        # 进入新建数据接口界面
        status = self.find_element('first_level_menu_module', 'basic_available_configure_status')
        if "ivu-menu-opened" in status.get_attribute("class"):
            if self.quick_check_element('new_interface_module', 'select_ext_service_interface_protocol'):
                pass
            else:
                self.click('second_level_menu_module', 'new_interface')
                self.soft_assert_element_visible('new_interface_module', 'select_ext_service_interface_protocol')
        else:
            self.click('first_level_menu_module', 'basic_available_configure')
            self.soft_assert_element_visible('second_level_menu_module', 'new_interface')
            self.click('second_level_menu_module', 'new_interface')
            self.soft_assert_element_visible('new_interface_module', 'select_ext_service_interface_protocol')

    def delete_interface_page(self, interface_name):
        """
        支持分页查找并删除对象
        :param interface_name: 要删除的对象名称
        """
        if self.quick_check_element('common_elements', 'no_data'):
            pass
        else:
            current_page = 1
            while True:
                # 获取当前页所有对象名称
                name_elements = self.find_elements('new_interface_module', 'interface_name_all')
                # 遍历当前页
                for row_index, element in enumerate(name_elements, 1):
                    if element.text.strip() == interface_name:
                        self._delete_current_row(row_index)
                        if self.quick_check_element('common_elements', 'delete_success'):
                            self.logger.info(f"成功删除第{current_page}页的'{interface_name}'")
                        else:
                            self.logger.info(f"未成功删除第{current_page}页的'{interface_name}'")
                        return
                # 尝试翻页
                if not self._go_to_next_page():
                    break
                current_page += 1 # 等待分页加载

    def _delete_current_row(self, row_index):
        """执行单行删除操作"""
        delete_btn = self.find_dynamic_element(
            'new_interface_module',
            'delete_interface_all',
            row_index
        )
        # 点击删除按钮
        delete_btn.click()
        self.click('common_elements', 'confirm_button')
        self.find_element('common_elements', 'delete_success')

    def update_interface_status(self, interface_name, interface_status):
        """ 修改接口状态 """
        self.enter_new_interface_page()
        if self.quick_check_element('common_elements', 'no_data'):
            pass
        else:
            result =  self.query_paged_data(
                search_locator='interface_name_all',
                target_locator='interface_status_all',
                value=interface_name,
                param_name='interface_name'
            )
            if result is None:
                pass
            else:
                if "ivu-switch-checked" in result.get_attribute("class"):
                    if interface_status == '启动':
                        pass
                    else:
                        result.click()
                        self.find_element('common_elements', 'status_update_success')
                        self.logger.info(f"接口 '{interface_name}'停止成功")
                else:
                    if interface_status == '停止':
                        pass
                    else:
                        result.click()
                        self.find_element('common_elements', 'status_update_success')
                        self.logger.info(f"接口 '{interface_name}'启动成功")

    def newly_built_interface(self):
        # 点击新建按钮
        self.click('common_elements', 'newly_built')
        self.soft_assert_element_visible('new_interface_module', 'interface_new_interface_title')

    def input_belong_to_object(self, belong_to_object):
        """ 输入所属业务对象 """
        self.click('new_interface_module', 'belong_to_object')
        selected_result = self.select_interface_options(
            element_locator='input_belong_to_object',
            values=belong_to_object,
            param_name='belong_to_object'
        )
        self.soft_assert_text_equal('new_interface_module', 'belong_to_object', belong_to_object)
        return selected_result

    def input_interface_direction(self, direction):
        """输入数据接口方向"""
        self.click('new_interface_module', 'interface_direction')
        selected_result = self.select_interface_options(
            element_locator='input_interface_direction',
            values=direction,
            param_name='direction'
        )
        self.soft_assert_text_equal('new_interface_module', 'interface_direction', direction)
        return selected_result

    def input_token(self, direction, token_name):
        """输入令牌"""
        if direction == '请求方':
            self.click('new_interface_module', 'interface_token')
            selected_result =  self.select_interface_options(
                element_locator='input_interface_token',
                values=token_name,
                param_name='token_name'
            )
            self.soft_assert_text_equal('new_interface_module', 'interface_token', token_name)
            return selected_result
        else:
            pass

    def input_interface_name(self, interface_name):
        """ 输入数据的接口名称 """
        self.input_text('new_interface_module', 'input_interface_name', interface_name)
        # 验证结果
        self.soft_assert_input_value('new_interface_module', 'input_interface_name', interface_name)

    def input_interface_description(self, description):
        """ 输入数据的接口说明 """
        self.input_text('new_interface_module', 'interface_description', description)
        self.soft_assert_input_value('new_interface_module', 'interface_description', description)

    def input_server_protocol(self, server_protocol):
        """ 选择服务路口接口协议 """
        assert server_protocol in ('HTTP', 'HTTPS'), f"无效协议类型: {server_protocol}"
        # 动态选择元素名
        element_name = f'server_protocol_{server_protocol.lower()}'
        # 点击操作
        self.click('new_interface_module', element_name)
        self.click('new_interface_module', element_name)

    def input_server_interface_ip(self, server_ip):
        """ 输入服务路口接口IP """
        self.input_text('new_interface_module', 'server_interface_ip', server_ip)
        # 验证结果
        self.soft_assert_input_value('new_interface_module', 'server_interface_ip', server_ip)

    def input_server_interface_port(self, server_port):
        """ 输入服务路口接口端口 """
        self.input_text('new_interface_module', 'server_interface_port', server_port)
        # 验证结果
        self.soft_assert_input_value('new_interface_module', 'server_interface_port', server_port)

    def input_server_interface_path(self, server_path):
        """ 输入服务路口接口路径 """
        self.input_text('new_interface_module', 'server_interface_path', server_path)
        # 验证结果
        self.soft_assert_input_value('new_interface_module', 'server_interface_path', server_path)

    def input_client_protocol(self, client_protocol):
        """ 输入客户端接口协议 """
        assert client_protocol in ('HTTP', 'HTTPS'), f"无效协议类型: {client_protocol}"
        # 动态选择元素名
        element_name = f'client_protocol_{client_protocol.lower()}'
        # 点击操作
        self.click('new_interface_module', element_name)

    def input_client_req_method(self, req_method):
        """输入客户端请求方式"""
        # 统一转换为列表处理
        if req_method == '' or req_method == '全部':
            self.click('new_interface_module', 'client_req_method_all')
        else:
            selected_result =  self.select_interface_options(
                element_locator='client_req_method',
                values=req_method,
                param_name='req_method'
            )
            return selected_result

    def input_client_interface_ip(self, client_ip):
        """ 输入服务路口接口IP """
        self.input_text('new_interface_module', 'client_interface_ip', client_ip)
        # 验证结果
        self.soft_assert_input_value('new_interface_module', 'client_interface_ip', client_ip)

    def input_client_interface_port(self, client_port):
        """ 输入服务路口接口端口 """
        self.input_text('new_interface_module', 'client_interface_port', client_port)
        # 验证结果
        self.soft_assert_input_value('new_interface_module', 'client_interface_port', client_port)

    def input_client_interface_path(self, client_path):
        """ 输入服务路口接口路径 """
        self.input_text('new_interface_module', 'client_interface_path', client_path)
        # 验证结果
        self.soft_assert_input_value('new_interface_module', 'client_interface_path', client_path)

    def save_data_interface(self, interface_name):
        """ 保存数据接口 """
        self.click('new_interface_module', 'save_data_interface')
        self.find_interface_name(interface_name)
        self.find_element('common_elements', 'newly_built_success')
        self.logger.info(f'数据接口：{interface_name} 保存成功')

    """ #########################################  通用功能  ########################################## """

    def query_paged_data(self, search_locator: str, target_locator: str, value: str, param_name: str):
        """通用分页数据查询方法（返回符合的元素、单值）"""
        # 标准化输入值
        target_text = str(value).strip()
        current_page = 1

        while True:
            # 获取当前页所有可选项
            options = self.find_elements('new_interface_module', search_locator)

            # 遍历匹配选项
            for row_index, element in enumerate(options, 1):
                option_text = element.text.strip()
                if option_text == target_text:
                    # 获取同行的目标元素
                    target_element = self.find_dynamic_element(
                        'new_interface_module',
                        target_locator,
                        row_index
                    )
                    return target_element  # 直接返回元素
                    # return target_element.text.strip() #直接返回字符串

            # 尝试翻页
            if not self._go_to_next_page():
                self.logger.debug(f"未找到匹配项: {target_text}，已遍历 {current_page} 页")
                return None  # 静默返回None

            current_page += 1

    def select_interface_options(self, element_locator: str, values: list, param_name: str):
        """通用接口选项选择方法（基础方法）"""
        # 类型统一处理
        if not isinstance(values, list):
            values = [values]

        selected = []
        for value in values:
            # 获取所有可选项
            options = self.find_elements('new_interface_module', element_locator)

            # 标准化输入值
            target_text = str(value).strip()

            # 遍历匹配选项
            found = False
            for option in options:
                option_text = option.text.strip()
                if option_text == target_text:
                    self.highlight_element(option)  # 可视化点击元素
                    option.click()
                    selected.append(option_text)
                    found = True
                    break

            if not found:
                available_options = [opt.text.strip() for opt in options]
                raise ValueError(
                    f"参数 {param_name} 未找到选项: '{target_text}'\n"
                    f"可用选项: {available_options}"
                )
            return selected

    """ ##########################################  筛选功能  ########################################## """

    def select_ext_service_interface_protocol(self, server_protocol):
        """选择对外服务接口协议"""
        self.enter_new_interface_page()
        return self.select_interface_options(
            element_locator='select_ext_service_interface_protocol_all',
            values=server_protocol,
            param_name='server_protocol'
        )

    def select_int_req_interface_protocol(self, client_protocol):
        """选择对内请求接口协议"""
        return self.select_interface_options(
            element_locator='select_int_req_interface_protocol_all',
            values=client_protocol,
            param_name='client_protocol'
        )

    def select_ext_service_interface_method(self, req_method):
        """对外服务接口请求方法"""
        return self.select_interface_options(
            element_locator='select_ext_service_interface_method_all',
            values=req_method,
            param_name='req_method'
        )

    def select_interface_name(self, interface_name):
        """筛选数据接口名称"""
        self.enter_new_interface_page()
        status = self.find_element('new_interface_module', 'more_options')
        if "dropdown" in status.get_attribute("class"):
            status.click()
        else:
            pass
        self.input_text('new_interface_module', 'select_interface_name', interface_name)
        selected_result = self.select_interface_options(
            element_locator='select_interface_name_all',
            values=interface_name,
            param_name='interface_name'
        )
        self.soft_assert_input_value('new_interface_module', 'select_interface_name', interface_name)
        return selected_result

    def select_ext_server_ip(self, interface_name):
        """对外服务数据接口地址"""
        status = self.find_element('new_interface_module', 'more_options')
        if "dropdown" in status.get_attribute("class"):
            status.click()
        else:
            pass
        server_ip = self.get_interface_ip(interface_name)
        self.click('new_interface_module', 'select_ext_server_ip')
        selected_result = self.select_interface_options(
            element_locator='select_ext_server_ip_all',
            values=server_ip,
            param_name='server_ip'
        )
        self.soft_assert_input_value('new_interface_module', 'select_ext_server_ip', server_ip)
        return selected_result

    def select_int_req_ip(self, interface_name):
        """对内请求数据接口地址"""
        status = self.find_element('new_interface_module', 'more_options')
        if "dropdown" in status.get_attribute("class"):
            status.click()
        else:
            pass
        client_ip = self.get_int_interface_ip(interface_name)
        self.input_text('new_interface_module', 'select_int_req_ip', client_ip)
        selected_result = self.select_interface_options(
            element_locator='select_int_req_ip_all',
            values=client_ip,
            param_name='client_ip'
        )
        self.soft_assert_input_value('new_interface_module', 'select_int_req_ip', client_ip)
        return selected_result

    """ ##########################################  获取策略显示参数的功能  ########################################## """

    def find_interface_name(self, interface_name):
        """对外服务接口请求方法"""
        return self.select_interface_options(
            element_locator='interface_name_all',
            values=interface_name,
            param_name='interface_name'
        )

    def get_interface_direction(self, interface_name):
        """ 获取接口方向 """
        self.enter_new_interface_page()
        result =  self.query_paged_data(
            search_locator='interface_name_all',
            target_locator='interface_direction_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的接口方向：{result}")
        return result

    def get_ext_interface_protocol(self, interface_name):
        """ 获取对外接口协议 """
        self.enter_new_interface_page()
        result =  self.query_paged_data(
            search_locator='interface_name_all',
            target_locator='interface_ext_protocol_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的对外接口协议：{result}")
        return result

    def get_interface_ip(self, interface_name):
        """ 获取接口对外IP地址（直接返回字符串）"""
        self.enter_new_interface_page()
        result =  self.query_paged_data(
            search_locator='interface_name_all',
            target_locator='ext_server_interface_ip_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的对外地址：{result}")
        return result

    def get_ext_interface_method(self, interface_name):
        """ 获取对外请求方式 """
        self.enter_new_interface_page()
        result =  self.query_paged_data(
            search_locator='interface_name_all',
            target_locator='ext_server_interface_method_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的对外请求方式：{result}")
        return result

    def get_int_interface_ip(self, interface_name):
        """获取接口对内IP地址IP（直接返回字符串）"""
        self.enter_new_interface_page()
        result =  self.query_paged_data(
            search_locator='interface_name_all',
            target_locator='int_client_interface_ip_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的对内地址：{result}")
        return result

    def get_int_interface_protocol(self, interface_name):
        """ 获取对内请求接口协议 """
        self.enter_new_interface_page()
        result =  self.query_paged_data(
            search_locator='interface_name_all',
            target_locator='int_client_interface_protocol_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的对内请求接口协议：{result}")
        return result

    def get_create_time(self, interface_name):
        """ 获取策略创建时间 """
        self.enter_new_interface_page()
        result =  self.query_paged_data(
            search_locator='interface_name_all',
            target_locator='create_time',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的策略创建时间：{result}")
        return result

    """ ##########################################  导出功能  ########################################## """

    def export_interface(self, token_name, token_code, interface_name, direction,
                         description, server_ip, server_protocol, client_ip, client_protocol,
                         req_method, create_interface_time, interface_status):
        # 导出筛选后的数据接口
        self.click('common_elements', 'export')
        excel_file = self.excel_processor.wait_for_new_excel(timeout=60)

        # 定义解析参数
        parse_params = {
            "sheet_name": "1-100",
            "start_row": 3,
            "headers": ["序号", "所属服务", "数据接口令牌码名称", "数据接口令牌码", "数据接口名称", "数据接口方向", "数据接口说明"
                        , "对内请求数据接口地址", "对内请求数据接口协议", "对外服务数据接口地址", "对外服务数据接口协议",
                        "对外服务数据接口请求方法", "创建时间", "启/停"],
            "max_rows": 10
        }

        # 解析Excel内容
        excel_data = self.excel_processor.parse_excel(excel_file, parse_params)

        # 只处理第一个数据条目
        for item in excel_data:
            # 记录完整数据
            self.logger.info("正在验证导出的接口数据：")
            for key, value in item.items():
                self.logger.info(f"{key}: {value}")

            # 数据预处理
            token_name = None if str(token_name).strip() == '' else token_name
            token_code = None if str(token_code).strip() == '' else token_code
            excel_values = {
                '数据接口令牌码名称': str(item.get('数据接口令牌码名称', '')).strip() or None,
                '数据接口令牌码': str(item.get('数据接口令牌码', '')).strip() or None,
                '数据接口名称': str(item.get('数据接口名称', '')).strip(),
                '数据接口方向': str(item.get('数据接口方向', '')).strip(),
                '数据接口说明': str(item.get('数据接口说明', '')).strip(),
                '对内请求数据接口地址': str(item.get('对内请求数据接口地址', '')).strip(),
                '对内请求数据接口协议': str(item.get('对内请求数据接口协议', '')).strip(),
                '对外服务数据接口地址': str(item.get('对外服务数据接口地址', '')).strip(),
                '对外服务数据接口协议': str(item.get('对外服务数据接口协议', '')).strip(),
                '对外服务数据接口请求方法': str(item.get('对外服务数据接口请求方法', '')).strip(),
                '创建时间': str(item.get('创建时间', '')).strip(),
                '启/停': str(item.get('启/停', '')).strip()
            }

            # 字段比较验证
            comparisons = [
                ('数据接口令牌码名称', excel_values['数据接口令牌码名称'], token_name),
                ('数据接口令牌码', excel_values['数据接口令牌码'], token_code),
                ('数据接口名称', excel_values['数据接口名称'], interface_name),
                ('数据接口方向', excel_values['数据接口方向'], direction),
                ('数据接口说明', excel_values['数据接口说明'], description),
                ('对内请求数据接口地址', excel_values['对内请求数据接口地址'], server_ip),
                ('对内请求数据接口协议', excel_values['对内请求数据接口协议'], server_protocol),
                ('对外服务数据接口地址', excel_values['对外服务数据接口地址'], client_ip),
                ('对外服务数据接口协议', excel_values['对外服务数据接口协议'], client_protocol),
                ('对外服务数据接口请求方法', excel_values['对外服务数据接口请求方法'], req_method),
                ('创建时间', excel_values['创建时间'], create_interface_time),
                ('启/停', excel_values['启/停'], interface_status)
            ]

            # 执行所有字段比较
            all_match = True
            for field, actual, expected in comparisons:
                # 统一None处理
                actual = actual if actual != 'None' else None
                expected = str(expected).strip() if expected is not None else None
                if actual == expected:
                    self.logger.info(f"{field}匹配成功: {actual}")
                else:
                    all_match = False
                    self.logger.error(f"{field}匹配失败 | Excel值: {actual} | 期望值: {expected}")

            # 输出最终结果
            if all_match:
                self.logger.info("所有字段验证通过")
            else:
                self.logger.error("存在字段验证失败")

            # 无论是否匹配，执行一次后退出循环
            break